#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include <chrono>

float positions[8] = {
    -0.5f, -0.5f,
     0.5f, -0.5f,
    -0.5f,  0.5f,
     0.5f,  0.5f
};

// 绘制一个简单的矩形
void drawRectangle() {
    glBegin(GL_QUADS);
    glColor3f(0.2f, 0.6f, 0.8f);  // 蓝绿色
    glVertex2f(-0.5f, -0.5f);
    glVertex2f( 0.5f, -0.5f);
    glVertex2f( 0.5f,  0.5f);
    glVertex2f(-0.5f,  0.5f);
    glEnd();
}

// 回调函数：窗口大小改变时调整视口
void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
    glViewport(0, 0, width, height);
}

int main() {
    if (!glfwInit()) {
        std::cerr << "Failed to initialize GLFW\n";
        return -1;
    }

    GLFWwindow* window = glfwCreateWindow(800, 600, "GLFW Simple UI", nullptr, nullptr);
    if (!window) {
        std::cerr << "Failed to create window\n";
        glfwTerminate();
        return -1;
    }

    glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

    glfwMakeContextCurrent(window);
    glfwSwapInterval(1);  // 开启垂直同步

    if (glewInit() != GLEW_OK) {
        std::cerr << "Failed to initialize GLEW\n";
        glfwDestroyWindow(window);
        glfwTerminate();
        return -1;
    }

    // 生成并绑定 VAO（Vertex Array Object）
    GLuint VAO;
    glGenVertexArrays(1, &VAO);
    glBindVertexArray(VAO);

    
    // 生成并绑定 VBO（Vertex Buffer Object）
    GLuint VBO;
    glGenBuffers(1, &VBO);
    glBindBuffer(GL_ARRAY_BUFFER, VBO);  // 绑定到顶点缓冲区
    glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW); // 复制顶点数据


    // 告诉 OpenGL 如何解释顶点数据
    glVertexAttribPointer(
        0,                  // 顶点属性位置（layout(location = 0)）
        2,                  // 每个顶点2个分量
        GL_FLOAT,           // 类型是 float
        GL_FALSE,           // 不需要归一化
        2 * sizeof(float),  // 步长为3个 float
        (void*)0            // 从头开始读取数据
    );

    glEnableVertexAttribArray(0); // 启用位置0的顶点属性
    
    // 顶点着色器代码（GLSL）
    const char* vertexShaderSource = R"(
        #version 330 core
        layout(location = 0) in vec2 aPos; // 顶点位置
        void main() {
            gl_Position = vec4(aPos, 0, 1.0); // 输出裁剪空间坐标
        }
    )";

    // 片段着色器代码
    const char* fragmentShaderSource = R"(
        #version 330 core
        out vec4 FragColor;
        void main() {
            FragColor = vec4(0.2, 0.6, 0.9, 1.0); // 输出颜色（蓝绿色）
        }
    )";

    
    // 编译顶点着色器
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
    glCompileShader(vertexShader);

    // 编译片段着色器
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
    glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
    glCompileShader(fragmentShader);

    
    // 创建着色器程序并链接两个着色器
    GLuint shaderProgram = glCreateProgram();
    glAttachShader(shaderProgram, vertexShader);
    glAttachShader(shaderProgram, fragmentShader);
    glLinkProgram(shaderProgram);

    // 删除着色器对象（已链接可释放）
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);

    // 主循环
    auto lastTime = std::chrono::high_resolution_clock::now();
    int frameCount = 0;

    while (!glfwWindowShouldClose(window)) {
        // 计算帧率
        auto now = std::chrono::high_resolution_clock::now();
        frameCount++;
        double elapsed = std::chrono::duration<double>(now - lastTime).count();
        if (elapsed >= 1.0) {
            std::cout << "FPS: " << frameCount / elapsed << std::endl;
            std::cout << glGetString(GL_VERSION) << std::endl;
            frameCount = 0;
            lastTime = now;
        }

        // 处理输入
        if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
            glfwSetWindowShouldClose(window, true);

        // 设置背景色
        glClearColor(0.1f, 0.1f, 0.1f, 1.0f);  // 暗灰
        glClear(GL_COLOR_BUFFER_BIT);

        // 使用着色器程序
        glUseProgram(shaderProgram);
        glBindVertexArray(VAO);                // 绑定 VAO（包括 VBO 和属性配置）

        // 绘制矩形
        glDrawArrays(GL_TRIANGLE_STRIP, 0, 8);

        // 交换缓冲区 + 处理事件
        glfwSwapBuffers(window);
        glfwPollEvents();
    }

    // 释放资源
    glDeleteVertexArrays(1, &VAO);
    glDeleteBuffers(1, &VBO);
    glDeleteProgram(shaderProgram);

    // 销毁窗口和终止 GLFW
    glfwDestroyWindow(window);
    glfwTerminate();
    return 0;
}
